home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 276-300 / 299 / rxil / src / launch.c < prev    next >
C/C++ Source or Header  |  1995-03-14  |  5KB  |  244 lines

  1. /* launch.c */
  2.  
  3. /*        Copyright © 1989 by Donald T. Meyer, Stormgate Software
  4.  *        All Rights Reserved
  5.  */
  6.  
  7.  
  8.  
  9. #include "rxil.h"
  10.  
  11. #include <string.h>
  12.  
  13.  
  14.  
  15. /* NAME
  16.  *        RxilLaunch
  17.  *
  18.  * SYNOPSIS
  19.  *        result = RxilLaunch( rxi )
  20.  *
  21.  *        LONG result;
  22.  *
  23.  *        struct RxilInvocation *rxi;
  24.  *
  25.  * FUNCTION
  26.  *        Launch an ARexx program by sending an invocation message
  27.  *        to the RexxMaster process.  The RxilInvocation structure
  28.  *        which is allocated prior to this call via RxilCreateRxi()
  29.  *        contains the information neccessary to launch the program.
  30.  *
  31.  * INPUTS
  32.  *        rxi        A pointer to an initialized RxilInvocation structure.
  33.  *
  34.  * RESULT
  35.  *        Zero if the launch was successful, non-zero otherwise.
  36.  *
  37.  * SIDES
  38.  *
  39.  * HISTORY
  40.  *        01-Aug-89    Creation.
  41.  *
  42.  * BUGS
  43.  *
  44.  * SEE ALSO
  45.  *        RxilCreateRxi(), RxilDeleteRxi()
  46.  */
  47.  
  48. LONG RxilLaunch( struct RxilInvocation *rxi )
  49. {
  50.     struct RexxArg *arg;
  51.     struct MsgPort *rmast, *replyport;
  52.     struct RexxMsg *rexxmsg;
  53.     int i;
  54.     int ac=0;
  55.     UWORD len;
  56.  
  57.  
  58.     /* Make call "safe" even if RxilInit() failed */
  59.     if( global_rdef == NULL )
  60.     {
  61.         return( -1 );
  62.     }
  63.  
  64.  
  65.     /* Replys can come in at either port. */
  66.     replyport = global_rdef->SecretPort ?
  67.         global_rdef->SecretPort : global_rdef->PublicPort;
  68.  
  69.  
  70.     if( rxi->State != RXIL_STATE_AVAILABLE )
  71.     {
  72.         /* A command is already launched, (using this structure),
  73.          * or the reply has not yet been dealt with.
  74.          */
  75.         return( -1 );
  76.     }
  77.  
  78.  
  79.     /* Allocate a packet to send to rexxmaster */
  80.     rexxmsg = CreateRexxMsg( replyport, rxi->FileExt, rxi->CommAddr );
  81.     if( rexxmsg == NULL )
  82.     {
  83.         return( -1 );
  84.     }
  85.  
  86.     /* Allocate an argument string for the command name and args */
  87.     arg = CreateArgstring(  rxi->Name, strlen( rxi->Name )  );
  88.     if( arg == NULL )
  89.     {
  90.         DeleteRexxMsg( rexxmsg );
  91.         return( -1 );
  92.     }
  93.  
  94.     ARG0(rexxmsg) = (STRPTR)arg;
  95.  
  96.  
  97.     if( rxi->Type == RXFUNC )
  98.     {
  99.         /* This is a Function invocation. */
  100.  
  101.         /* Turn the arguments into Rexx Argstrings and place in the
  102.          * RexxMsg packet.
  103.          */
  104.         for( i=1; i<=MAXRMARG; i++ )
  105.         {
  106.             if( rxi->FuncArg[i] == NULL )
  107.             {
  108.                 /* Empty argument slot, consider it the last */
  109.                 break;
  110.             }
  111.  
  112.             /* We can either determine the argument length, or the client
  113.              * can pre-set a count.
  114.              */
  115.             len = rxi->CountArgs ?
  116.                 rxi->ArgLen[i] : strlen(rxi->FuncArg[i]);
  117.  
  118.             rexxmsg->rm_Args[i] =
  119.                 (STRPTR)CreateArgstring( rxi->FuncArg[i], len );
  120.  
  121.             ac++;
  122.  
  123.             if( rexxmsg->rm_Args[i] == NULL )
  124.             {
  125.                 /* Unable to create this argstring.  Cleanup and return
  126.                  * a failure code.
  127.                  */
  128.                 for( i=0; i<=MAXRMARG; i++ )
  129.                 {
  130.                     if( rexxmsg->rm_Args[i] != NULL )
  131.                     {
  132.                         DeleteArgstring( (struct RexxArg *)
  133.                             (rexxmsg->rm_Args[i]) );
  134.                     }
  135.                 }
  136.  
  137.                 DeleteRexxMsg( rexxmsg );
  138.                 return( -1 );
  139.             }
  140.         }
  141.  
  142.         rexxmsg->rm_Action = RXFUNC | rxi->ActionFlags | ac;
  143.     }
  144.     else
  145.     {
  146.         /* This is a Command invocation */
  147.          rexxmsg->rm_Action = RXCOMM | rxi->ActionFlags;
  148.     }
  149.  
  150.  
  151.     /* Set up the I/O streams for the macro */
  152.  
  153.     if( rxi->Parent == NULL )
  154.     {
  155.         /* This is an original launch from the application */
  156.         if( rxi->Console )
  157.         {
  158.             /* And there is a console spec.  Use it. */
  159.             RxilOpenConsole( rxi->Console, rexxmsg );
  160.         }
  161.     }
  162.     else
  163.     {
  164.         /* This is a loopback child of a macro.  Use the I/O fields
  165.          * from the parent message.
  166.          */
  167.         rexxmsg->rm_Stdin = rxi->Parent->rm_Stdin;
  168.         rexxmsg->rm_Stdout = rxi->Parent->rm_Stdout;
  169.     }
  170.  
  171.  
  172.     Forbid();
  173.     if(   (  rmast = FindPort( rxi->IHostPort )  ) != NULL   )
  174.     {
  175.         PutMsg( rmast, (struct message *)rexxmsg );
  176.     }
  177.     Permit();
  178.  
  179.     if( rmast == NULL )
  180.     {
  181.         /* we could not find the REXX port, this failed!
  182.          * Cleanup and return a failure code.
  183.          */
  184.         for( i=0; i<=MAXRMARG; i++ )
  185.         {
  186.             if( rexxmsg->rm_Args[i] != NULL )
  187.             {
  188.                 DeleteArgstring( (struct RexxArg *)
  189.                     (rexxmsg->rm_Args[i]) );
  190.             }
  191.         }
  192.  
  193.         if( rxi->Console )
  194.         {
  195.             RxilCloseConsole( rexxmsg );
  196.         }
  197.  
  198.         DeleteRexxMsg( rexxmsg );
  199.         return( -1 );
  200.     }
  201.  
  202.  
  203.     /* If we make it here, we have hopefully launched. */
  204.  
  205.     /* Set this so we can recognize the reply, and to let us know that
  206.      * we have a command pending.
  207.      */
  208.     rxi->RexxMsg = rexxmsg;
  209.     rxi->State = RXIL_STATE_PENDING;
  210.  
  211.  
  212.     if( rxi->CommAddr == global_rdef->SecretPortName )
  213.     {
  214. #if 0
  215.         if( global_rdef->Locked  )
  216.         {
  217.             /* Since we are locked, we should not be launching any macros
  218.              * which have the secret port as their initial host address.
  219.              */
  220.             return( -1 );
  221.         }
  222. #endif
  223.  
  224.         /* Increment the locked count.
  225.          */
  226.         global_rdef->LockCount++;
  227.     }
  228.  
  229.  
  230.     if( rxi->Parent == NULL )
  231.     {
  232.         /* This is a launch originated within the application. */
  233.         if(  FlagIsClear( global_rdef->Flags, RXIL_NO_ABORT )  )
  234.         {
  235.             /* Post the macro cancel requester */
  236.             RxilPostCancel();
  237.         }
  238.     }
  239.  
  240.  
  241.     return( 0 );
  242. }
  243.  
  244.